package com.modulemanager.page

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Activity.OVERRIDE_TRANSITION_CLOSE
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.view.WindowCompat
import com.libbase.Weak
import com.libnetwork.Network
import com.libservice.RouteCompletion
import com.libservice.ServiceManager
import com.modulemanager.models.PageConfig
import com.modulemanager.module.ModuleInterface
import com.modulemanager.services.MockModuleAPI
import com.modulemanager.views.PageActivity
import com.modulemanager.views.PresentActivity
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers

abstract class Page(
    module: ModuleInterface,
    final override val type: String,
    final override val id: String?,
    config: PageConfig?,
    params: Map<String, Any>?,
    override val hash: String?,
) : PageInterface {
    companion object {
        private const val TAG: String = "ModuleManager"
    }

    override var context: Context? by Weak()

    final override var module: ModuleInterface? by Weak { module }

    override var params: MutableMap<String, Any>? = params?.toMutableMap()

    final override var config: PageConfig = config?.also { config ->
        params?.let { config.setValues(it) }
    } ?: PageConfig.Builder().also { builder -> params?.let { builder.setValues(it) } }.create()

    override var completion: RouteCompletion? = null

    override var completionParam: Any? = null

    override var popDelta: Int = 1

    init {
        Network.instance.serviceAddressRepository?.let {
            MockModuleAPI.pageValue(module.type, module.id, type, id)
                .observeOn(AndroidSchedulers.mainThread()).subscribe({ result ->
                    if (!result.isSuccess()) {
                        Log.e(TAG, result.message ?: "Request pageValue error!")
                        return@subscribe
                    }

                    val value: Map<String, Any> = result.data ?: return@subscribe

                    if (params == null) {
                        this.params = value.toMutableMap()
                        return@subscribe
                    }

                    this.params = params.plus(value).toMutableMap()
                }, { error ->
                    Log.e(TAG, error.localizedMessage ?: "请求模块配置失败！")
                })
        }
    }

    @SuppressLint("WrongConstant")
    override fun startActivity(intentFlags: Int?, animated: Boolean): Boolean {
        val module = this.module ?: return false

        val currentActivity: Activity =
            ServiceManager.instance.activityService.currentActivity ?: return false

        val intent = Intent(
            currentActivity, if (config.transitionType == "present") {
                PresentActivity::class.java
            } else {
                PageActivity::class.java
            }
        )
        intent.putExtra("moduleType", module.type)
        intentFlags?.let {
            intent.flags = it
        }

        if (module.id != null) {
            intent.putExtra("moduleId", module.id)
        }
        intent.putExtra("pageType", type)
        if (id != null) {
            intent.putExtra("pageId", id)
        }
        currentActivity.startActivity(intent)
        if (!animated) {
            if (Build.VERSION.SDK_INT >= 34) {
                currentActivity
                    .overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, 0, 0)
            } else {
                @Suppress("DEPRECATION")
                currentActivity.overridePendingTransition(0, 0)
            }
        }

        return true
    }

    private fun setStatusBarType(statusBarType: PageConfig.StatusBarType?) {
        fragmentContainer.fragment.activity?.let {
            WindowCompat.getInsetsController(
                it.window, it.window.decorView
            ).isAppearanceLightStatusBars =
                statusBarType == PageConfig.StatusBarType.DARK
        }
    }

    override fun updateStatusBar() {
        setStatusBarType(config.statusBarType.value)
    }
}